package controllers.manager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import play.Logger;
import play.modules.market.MarketProfile;

import com.google.gdata.data.appsforyourdomain.provisioning.UserEntry;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import controllers.MarketController;
import controllers.Security;

import utils.api.service.MarketUserService;
import utils.json.data.AbstractJson;
import utils.json.data.backbone.FocusJson;
import utils.json.data.backbone.RoleJson;
import utils.json.data.backbone.UserJson;
import utils.table.DataTable;
import utils.table.DataTable.DataTablesParameters;
import models.Focus;
import models.Profile;
import models.User;

public class ManagerController extends ManagerBaseController {
	public static void index() {
		render("manager/index.html");
	}
	
	public static void getGoogleSetup() {
		render("manager/setup.html");
	}
	
	public static void doGoogleSetup() {
		User manager = getCurrentUser();
		String setup_option = params.get("setup_option");
		if(manager != null && !isBlank(setup_option)) {
			if("automatic".equals(setup_option)) {
				addAllUsersFromGoogleDomain(manager);
				index();
			} else if("manual".equals(setup_option )) {
				index();
			}
			Logger.debug("El parametro es: %s", setup_option);
		} else {
			getGoogleSetup();
		}
	}
	
	public static void users() {
		final DataTablesParameters dtp = new DataTable.DataTablesParameters(request);
		
		DataTable<User> table = new DataTable<User>(User.all(), dtp);
		
		List<UserJson> jsonList = new ArrayList<UserJson>();
		for(User user : table.getRows()) {
			UserJson userJson = new UserJson(user);
			userJson.put("roles", new RoleJson(user));
			jsonList.add(userJson);
		}
		table.setRows(jsonList);
		
		renderJSON(table);
	}
	

	public static void googleusers() {
		User manager = getCurrentUser();
		List<UserEntry> entries = getUsersFromGoogleDomain(manager);
		
		List<UserJson> jsonList = new ArrayList<UserJson>();
		UserJson userJson = null;
		for(UserEntry userEntry : entries) {
			User user = User.findByProfileEmail(Profile.MARKET_PREFIX, userEntry.getLogin().getUserName()+"@"+manager.getProfile().getDomain());
			if(user != null) {
				Logger.debug("User %s was found!", user.getProfile().getEmail());
				userJson = new UserJson(user);
				userJson.put("roles", user.getRoles());
				userJson.put("roles", new RoleJson(user));
			} else {
				userJson = new UserJson(userEntry);
				userJson.put("roles", new RoleJson());
			}
			
			jsonList.add(userJson);
		}
		
		renderJSON(jsonList);
	}
	
	public static void updateuser(Long id, String body) {
		JsonObject jsonObject = new JsonParser().parse(body).getAsJsonObject();
		
		Boolean access = jsonObject.get("access") != null ? jsonObject.get("access").getAsBoolean() : null;
		
		JsonObject rolesJson = jsonObject.get("roles").getAsJsonObject();
		ArrayList<String> roles = new ArrayList<String>();
		for(String role : Security.ROLES) {
			if(rolesJson.get(role).getAsBoolean()) {
				roles.add(role);
			}
		}
		
		User user = User.findById(id);
		user.setRoles(roles);
		user.setAccess(access);
		user.save();
		
		ok();
	}
	
	/*public static void deleteUser(Long id) {
		User manager = getCurrentUser();
		User user = User.findById(id);
		MarketUserService userService = new MarketUserService(manager.getProfile().getEmail(), manager.getProfile().getDomain());
		UserEntry userEntry = userService.retrieveUser(user.getProfile().getEmail().substring(0, user.getProfile().getEmail().indexOf("@")));
		user.delete();
		renderJSON(new UserJson(userEntry)); // TODO 500 error!
	}*/

	public static void addgoogleusers(String body) {
		User manager = getCurrentUser();
		MarketUserService userService = new MarketUserService(manager.getProfile().getEmail(), manager.getProfile().getDomain());
		
		// Json data
		User user = null;
		JsonObject jsonObject = new JsonParser().parse(body).getAsJsonObject();
		String userName = jsonObject.get("userName") != null ? jsonObject.get("userName").getAsString() : null;
		String firstName = jsonObject.get("firstName") != null ? jsonObject.get("firstName").getAsString() : null;
		String lastName = jsonObject.get("lastName") != null ? jsonObject.get("lastName").getAsString() : null;
		String profileId = jsonObject.get("profileId") != null ? jsonObject.get("profileId").getAsString() : null;
		Boolean access = jsonObject.get("access") != null ? jsonObject.get("access").getAsBoolean() : Boolean.FALSE;
		
		if(!isBlank(userName)) {
			MarketProfile profile = new MarketProfile(profileId, userName+"@"+userService.getDomain(), firstName, lastName, manager.getProfile().getDomain());
			user = new User(new Profile(profile));
			user.setAccess(access);
			user.save();
			renderJSON(new UserJson(user));
		} 
		error("ERRRORRRR");
	}
	
	private static void addAllUsersFromGoogleDomain(User manager) {
		List<UserEntry> entries = getUsersFromGoogleDomain(manager);
		String domain = manager.getProfile().getDomain();
		
		for(UserEntry userEntry : entries) {
			MarketProfile profile = new MarketProfile(userEntry.getId(), 
					userEntry.getLogin().getUserName()+"@"+domain, 
					userEntry.getName().getGivenName(),
					userEntry.getName().getFamilyName(),
					domain);
			
			// Check if this user was added before
			User oldUser = User.findByProfileEmail(Profile.MARKET_PREFIX, profile.getEmail());
			if(oldUser == null) {
				User user = createUser(new Profile(profile));
				user.save();
			} else {
				oldUser.setAccess(Boolean.TRUE);
				oldUser.save();
			}
		}
		
	}
	
	private static List<UserEntry> getUsersFromGoogleDomain(User manager) {
		MarketUserService userService = new MarketUserService(manager.getProfile().getEmail(), manager.getProfile().getDomain());
		List<UserEntry> entries = userService.getUsersDomain();
		
		return entries;
	}
	
	private static User createUser(Profile profile) {
		User user = new User(profile);
		
		return user;
	}
	
	public static class RoleJson extends AbstractJson {
		
		public RoleJson() {
			for(String role : Security.ROLES) {
				this.put(role, Boolean.FALSE);
			}
		}
		
		public RoleJson(User user) {
			this();
			this.checkUserRoles(user);
		}
		
		private void checkUserRoles(User user) {
			Iterator<String> rolesIt = this.keySet().iterator();
			while(rolesIt.hasNext()) {
				String role = rolesIt.next();
				if(user.getRoles() != null && user.getRoles().contains(role)) this.put(role, Boolean.TRUE);
			}
		}
	}
}
